package com.greate.community.service;

import com.greate.community.dao.LikeMapper;
import com.greate.community.entity.Like;
import com.greate.community.constant.CommunityConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

/**
 * 点赞相关
 */
@Service
public class LikeService implements CommunityConstant {

    @Autowired
    private LikeMapper likeMapper;

    @Autowired
    private DiscussPostService discussPostService;

    @Autowired
    private CommentService commentService;

    @Autowired
    private UserService userService;

    /**
     * 点赞
     *
     * @param userId       点赞的用户 id
     * @param entityType   点赞实体类型
     * @param entityId     点赞实体 id
     * @param entityUserId 点赞实体对应用户 id
     */
    @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
    public void insertLike(int userId, int entityType, int entityId, int entityUserId) {
        // 判断是否点过赞
        int likeStatus = findEntityLikeStatus(userId, entityType, entityId);

        if (likeStatus == 1) {
            // 如果用户已经点过赞，点第二次则取消赞
            likeMapper.deleteLikeByUserIdAndEntity(userId, entityType, entityId);
            cancelLikeEntity(entityType, entityId, entityUserId);
        } else {
            Like like = new Like();
            like.setUserId(userId);
            like.setEntityType(entityType);
            like.setEntityId(entityId);
            like.setEntityUserId(entityUserId);
            like.setCreateTime(new Date());
            int result = likeMapper.insertLike(like);
            if (result == 1) {
                likeEntity(entityType, entityId, entityUserId);
            }
        }
    }

    /**
     * 查询某实体被点赞的数量
     *
     * @param entityType
     * @param entityId
     * @return
     */
    public long findEntityLikeCount(int entityType, int entityId) {
        long count = 0;
        if (entityType == ENTITY_TYPE_POST) {
            count = discussPostService.findDiscussPostById(entityId).getLikeCount();
        } else if (entityType == ENTITY_TYPE_COMMENT) {
            count = commentService.findCommentById(entityId).getLikeCount();
        } else if (entityType == ENTITY_TYPE_USER) {
            count = userService.findUserById(entityId).getLikeCount();
        }
        return count;
    }

    /**
     * 获取被点赞的目标实体
     *
     * @param entityType
     * @param entityId
     * @return
     */
    public Object getLikeTargetEntity(int entityType, int entityId) {
        Object object = null;
        if (entityType == ENTITY_TYPE_POST) {
            object = discussPostService.findDiscussPostById(entityId);
        } else if (entityType == ENTITY_TYPE_COMMENT) {
            object = commentService.findCommentById(entityId);
        } else if (entityType == ENTITY_TYPE_USER) {
            object = userService.findUserById(entityId);
        }
        return object;
    }

    /**
     * 查询某个用户对某个实体的点赞状态（是否已赞）
     *
     * @param userId
     * @param entityType
     * @param entityId
     * @return 1:已赞，0:未赞
     */
    public int findEntityLikeStatus(int userId, int entityType, int entityId) {
        return likeMapper.countLikeByUserIdAndEntity(userId, entityType, entityId) > 0 ? 1 : 0;
    }

    @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
    public int likeEntity(int entityType, int entityId, int entityUserId) {
        int result = 0;
        if (entityType == ENTITY_TYPE_POST) {
            result = discussPostService.like(entityId);
        } else if (entityType == ENTITY_TYPE_COMMENT) {
            result = commentService.like(entityId);
        }
        if (result == 1) {
            result = userService.like(entityUserId);
        }
        return result;
    }

    @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
    public int cancelLikeEntity(int entityType, int entityId, int entityUserId) {
        int result = 0;
        if (entityType == ENTITY_TYPE_POST) {
            result = discussPostService.cancelLike(entityId);
        } else if (entityType == ENTITY_TYPE_COMMENT) {
            result = commentService.cancelLike(entityId);
        }
        if (result == 1) {
            result = userService.cancelLike(entityUserId);
        }
        return result;
    }
}

